package com.steerinfo.dil;


import com.alibaba.fastjson.JSONObject;
import com.steerinfo.dil.feign.AmsFeign;
import com.steerinfo.dil.feign.RmsFeign;
import com.steerinfo.dil.mapper.ScTaskMapper;
import com.steerinfo.dil.model.ScTask;
import com.steerinfo.dil.util.DataChange;
import com.steerinfo.dil.util.HTTPRequestUtils;
import com.steerinfo.dil.util.HttpUtil;
import com.steerinfo.framework.utils.web.HttpUtils;
import org.apache.shiro.crypto.hash.Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@Component
@EnableScheduling
@Configurable
public class SpringCronTask implements SchedulingConfigurer{
	
	private static final Logger logger = LoggerFactory.getLogger(SpringCronTask.class);
	
	private ScheduledTaskRegistrar taskRegistrar;
	
	private Map<String, ScheduledFuture<?>> taskFutures = new ConcurrentHashMap<String, ScheduledFuture<?>>();
	
	@Autowired
    private JdbcTemplate jdbcTemplate;

	@Autowired
	private AmsFeign amsFeign;

	@Autowired
	private RmsFeign rmsFeign;

	@Autowired
	private ScTaskMapper scTaskMapper;

	static final String host = "http://172.16.90.202:8000";

	/**
	 * SchedulingConfigurer接口的方法实现，加载后自动运行
	 */
	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		//如果客户需要改动业务的执行时间,即动态地调整定时任务的执行时间,便使用ScheduledTaskRegistrar接口
		ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
		taskScheduler.setThreadNamePrefix("atwl-task");
		taskScheduler.setPoolSize(10);
		taskScheduler.initialize();
		taskRegistrar.setTaskScheduler(taskScheduler);
		this.taskRegistrar = taskRegistrar;
		// 初始化任务
		String sql = "select * from SC_TASK order by TIMINGID";
		List<Map<String, Object>> l = jdbcTemplate.queryForList(sql);
		if (l!=null && l.size()>0){
			for(int i =0; i<l.size(); i++){
				Map<String, Object> m = (Map<String, Object>)l.get(i);
				String taskId = m.get("TIMINGID").toString();
				String cron = m.get("TIMINGCRON").toString();
				String status = m.get("STATUS") == null ? "" : m.get("STATUS").toString();
				if(status.equalsIgnoreCase("1") && !taskFutures.containsKey(taskId)){
					addTask(taskId, cron);
				}
				if(status.equalsIgnoreCase("0") && taskFutures.containsKey(taskId)){
					cancelTriggerTask(taskId);
				}
				logger.info("定时任务-" + taskId + " cron表达式：" + cron);
			}
		}
	}
	
	/**
	 * 添加定时任务(初始化)
	 * 
	 * @param taskId
	 * @param cron
	 */
	public void addTask(String taskId, String cron) {
		if (!taskFutures.containsKey(taskId)) {
			TaskScheduler scheduler = taskRegistrar.getScheduler();
			ScheduledFuture<?> future = scheduler.schedule(doTask(taskId), new CronTrigger(cron));
			taskFutures.put(taskId, future);
			logger.info("当前定时任务队列长度：" + taskFutures.size());
		} else {
			throw new SchedulingException("the taskId[" + taskId + "] was added.");
		}
	}
	
	/**
	 * 添加或者更新定时任务
	 * 
	 * @param taskId
	 */
	public void updateTask(String taskId) {
		if(taskFutures.containsKey(taskId)){
			cancelTriggerTask(taskId);
		}
		TaskScheduler scheduler = taskRegistrar.getScheduler();
		ScheduledFuture<?> future = scheduler.schedule(doTask(taskId), new CronTrigger(getCron(taskId)));
		taskFutures.put(taskId, future);
		logger.info("当前定时任务队列长度：" + taskFutures.size());
	}
	
	/**
	 * 取消任务
	 * @param taskId
	 */
	public void cancelTriggerTask(String taskId){
		ScheduledFuture<?> future = taskFutures.get(taskId);
	      if (future != null){
	         future.cancel(true);
	      }
	      taskFutures.remove(taskId);
	}
	
	/**
	 * 业务处理
	 * 
	 * @param taskId
	 * @return
	 */
	private Runnable doTask(String taskId) {
		Properties props = System.getProperties(); // 系统属性
		return new Runnable() {
            @Override
            public void run() {
				//本机调试的话请注释这段代码或者将linux改成本机系统
				try {
//					if(!props.getProperty("os.name").equalsIgnoreCase("Linux")){
//						System.out.println("操作系统：" + props.getProperty("os.name") + ", 非linux环境不运行定时任务");
//						return;
//					}
					if (taskId.equalsIgnoreCase("101")) { // 定时任务1的业务处理-超出截止时间，自动关闭运输需求，同时推送信息至物流公司调度；小于截止时间，每天0点生成需求至待申报状态；
						logger.info("定时任务触发时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
						amsFeign.amsTransRequirementcorn();
						long start = System.currentTimeMillis();
						logger.info("定时任务"+taskId+"执行时长：" + (new Date().getTime() - start)/1000 + "秒");
					}else if (taskId.equalsIgnoreCase("104")) { // 定时任务2的业务处理-根据固定需求自动生成需求 晚班
						logger.info("定时任务触发时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
						Map<String, Object> map = new HashMap<>();
						map.put("status",1);
						amsFeign.ScheduledDispatch(map);
						long start = new Date().getTime();
						logger.info("定时任务"+taskId+"执行时长：" + (new Date().getTime() - start)/1000 + "秒");
					}else if (taskId.equalsIgnoreCase("103")) { // 定时任务2的业务处理-根据固定需求自动生成需求 早班
						logger.info("定时任务触发时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
						Map<String, Object> map = new HashMap<>();
						map.put("status",2);
						amsFeign.ScheduledDispatch(map);
						long start = new Date().getTime();
						logger.info("定时任务"+taskId+"执行时长：" + (new Date().getTime() - start)/1000 + "秒");
					}
					else {
						//从数据库获取定时任务并执行
						ScTask task =  scTaskMapper.selectByPrimaryKey(DataChange.dataToBigDecimal(taskId));
						if(task != null && task.getAlternateFields1()!= null && !task.getAlternateFields1().equals("")){
							logger.info("定时任务触发时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
							String url = host + task.getAlternateFields1();
							logger.info(task.getDescription()+",请求:"+url);
							JSONObject response = HttpUtil.sendPost(url,new JSONObject());
							logger.info(task.getDescription()+",返回:"+response);
						}
					}
				}catch (Exception e){
					e.printStackTrace();
				}
			}
        };
	}


	
	/**
	 * 获取任务时间表达式
	 * @param taskId
	 * @return
	 */
	public String getCron(String taskId) {
		String sql = "select cron from SC_TASK t where id = ?";
		return jdbcTemplate.queryForObject(sql, new Object[]{taskId}, String.class);
    }
}
